package com.mind.adjust.controller;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.read.listener.ReadListener;
import com.mind.adjust.domain.vo.AdjustCheckResult;
import com.mind.adjust.domain.vo.PatchCallback;
import com.mind.adjust.domain.vo.SmartCheckResultVo;
import com.mind.common.utils.poi.ExcelUtil;
import com.mind.common.utils.poi.ImportExcelResult;
import com.mind.common.utils.poi.ValidationUtils;
import com.mind.system.domain.AjCheckResult;
import com.mind.adjust.service.AjCheckResultService;
import com.mind.common.web.controller.BaseController;
import com.mind.common.core.domain.AjaxResult;
import com.mind.common.web.page.TableDataInfo;
import com.mind.common.log.annotation.Log;
import com.mind.common.log.enums.BusinessType;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;

import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.ConstraintViolation;
import javax.xml.bind.JAXBException;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 智能审核模块/审核模块/检查结果管理
 *
 * @author makejava
 * @DocView.PathPrefix {{host}}/api/adjust
 * @since 2024-07-28 16:43:27
 */
@RestController
@RequestMapping("adjust/checkResult")
@Tag(name = "检查结果管理", description = "检查结果管理")
public class AjCheckResultController extends BaseController {


    /**
     * 服务对象
     */
    @Autowired
    private AjCheckResultService ajCheckResultService;

    /**
     * 获取检查结果列表
     *
     * @param checkResult 筛选条件
     * @return com.mind.system.domain.AjCheckResult
     */
//    @RequiresPermissions("adjust:checkResult:list")
    @Log(title = "检查结果列表", businessType = BusinessType.QUERY)
    @GetMapping("/list")
    @Operation(summary = "检查结果列表", description = "检查结果列表")
    public TableDataInfo list(AjCheckResult checkResult)
    {
        startPage();
        List<AjCheckResult> list = ajCheckResultService.selectCheckResultList(checkResult);
        return getDataTable(list);
    }
    
    /**
     * 检查结果导入
     *
     * @return 结果
     */
//    @RequiresPermissions("adjust:checkResult:import")
    @Log(title = "检查结果导入", businessType = BusinessType.IMPORT)
    @PostMapping("/import")
    @Operation(summary = "检查结果导入", description = "检查结果导入")
    public AjaxResult importExcel(MultipartFile file) throws IOException {
        List<AjCheckResult> cachedDataList = new ArrayList<>();
        List<ImportExcelResult> errorList = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), AjCheckResult.class, new ReadListener<AjCheckResult>() {

            @Override
            public void invoke(AjCheckResult data, AnalysisContext context) {
                Set<ConstraintViolation<AjCheckResult>> violations = ValidationUtils.getValidator().validate(data);
                if(violations.size() > 0){
                    throw new ExcelDataConvertException(context.readRowHolder().getRowIndex(), 0, null, null, "");
                }
                cachedDataList.add(data);
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
//                saveData();
            }

            /**
             * 加上存储数据库
             */
//            private void saveData() {
//                int i = ajCheckResultService.batchInsert(cachedDataList);
//            }

            /**
             * 在转换异常 获取其他异常下会调用本接口。抛出异常则停止读取。如果这里不抛出异常则 继续读取下一行。
             *
             * @param exception
             * @param context
             * @throws Exception
             */
            @Override
            public void onException(Exception exception, AnalysisContext context) {
                // 如果是某一个单元格的转换异常 能获取到具体行号
                // 如果要获取头的信息 配合invokeHeadMap使用
                if (exception instanceof ExcelDataConvertException) {
                    ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException)exception;
                    String errMsg = String.format("第%d行数据验证异常", excelDataConvertException.getRowIndex());
                    errorList.add(new ImportExcelResult(){{
                        setRow(excelDataConvertException.getRowIndex());
                        setCol(excelDataConvertException.getColumnIndex());
                        setError(errMsg);
                    }});
                }
            }
        }).sheet().doRead();
        if(errorList.size() > 0) {
            return AjaxResult.success(String.format("一共%d条，成功导入%d条，错误%d条。错误详情：%s", cachedDataList.size() + errorList.size(), cachedDataList.size(), errorList.size(), errorList.stream().map(ImportExcelResult::getError).collect(Collectors.joining("\r\n"))));
        }else{
            return AjaxResult.success(String.format("一共%d条，成功导入%d条，错误0条。", (cachedDataList.size()), cachedDataList.size()));
        }
    }

    /**
     * 附件类型下载模板
     * @return 结果
     */
    @Log(title = "检查结果下载模板", businessType = BusinessType.DOWNLOAD)
//    @RequiresPermissions("adjust:attachType:download")
    @GetMapping("/downloadTemplate")
    @Operation(summary = "检查结果下载模板", description = "检查结果下载模板")
    public void downloadTemplate(HttpServletResponse response) throws IOException {
        ExcelUtil<AjCheckResult> util = new ExcelUtil<>(AjCheckResult.class);
        String fileName =  URLEncoder.encode("检查结果模板", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        util.exportExcel(response, new ArrayList<>(), "检查结果数据");
    }
    
    /**
     * 检查结果导出
     * @param checkResult 筛选条件
     * @return 结果
     */
    @Log(title = "检查结果导出", businessType = BusinessType.EXPORT)
//    @RequiresPermissions("adjust:checkResult:export")
    @PostMapping("/export")
    @Operation(summary = "检查结果导出", description = "检查结果导出")
    public void export(HttpServletResponse response, AjCheckResult checkResult)
    {
        List<AjCheckResult> list = ajCheckResultService.selectCheckResultList(checkResult);
        ExcelUtil<AjCheckResult> util = new ExcelUtil<AjCheckResult>(AjCheckResult.class);
        util.exportExcel(response, list, "检查结果数据");
    }

    @GetMapping("/listByTicketId")
    @Operation(summary = "获取查验结果", description = "获取查验结果")
    public AjaxResult listByTicketId(@Parameter(description ="单据Id",required=true) @RequestParam("ticketId") String ticketId,@Parameter(description ="版本号",required=true) @RequestParam(name = "version", required = false) Integer version)
    {
        List<AjCheckResult> list = ajCheckResultService.selectCheckResultListByTicketId(ticketId, version);
        return success(list);
    }

    /**
     * 查验结果
     * @param ticketId
     * @param version
     * @return
     */
    @GetMapping("/smartCheckList")
    @Operation(summary = "查验结果", description = "查验结果")
    public AjaxResult smartCheckList(@Parameter(description ="单据Id",required=true) @RequestParam("ticketId") String ticketId,@Parameter(description ="版本号",required=true) @RequestParam(name = "version", required = false) Integer version)
    {
        SmartCheckResultVo smartCheckResultVo = ajCheckResultService.smartCheckList(ticketId, version);
        return success(smartCheckResultVo);
    }

    /**
     * 根据ID获取检查结果详情
     * @return com.mind.system.domain.AjCheckResult
     */
//    @RequiresPermissions("adjust:checkResult:query")
    @GetMapping(value = "/{checkResultId}")
    @Operation(summary = "获取检查结果详情", description = "获取检查结果详情")
    public AjaxResult getInfo(@Parameter(description ="结果Id",required=true) @PathVariable Long checkResultId)
    {
        return success(ajCheckResultService.selectCheckResultById(checkResultId));
    }

    /**
     * 新增检查结果
     * @return 结果
     */
    @PreAuthorize("@ss.hasPermi('adjust:checkResult:add')")
    @Log(title = "检查结果新增", businessType = BusinessType.INSERT)
    @PostMapping
    @Operation(summary = "检查结果新增", description = "检查结果新增")
    public AjaxResult add(@Validated @RequestBody AjCheckResult checkResult)
    {
        return toAjax(ajCheckResultService.insertCheckResult(checkResult));
    }

    /**
     * 修改检查结果
     * @return 结果
     */
    @PreAuthorize("@ss.hasPermi('adjust:checkResult:edit')")
    @Log(title = "检查结果修改", businessType = BusinessType.UPDATE)
    @PutMapping
    @Operation(summary = "检查结果修改", description = "检查结果修改")
    public AjaxResult edit(@Validated @RequestBody AjCheckResult checkResult)
    {
        return toAjax(ajCheckResultService.updateCheckResult(checkResult));
    }

    /**
     * 删除检查结果
     * @return 结果
     */
    @PreAuthorize("@ss.hasPermi('adjust:checkResult:remove')")
    @Log(title = "检查结果删除", businessType = BusinessType.DELETE)
    @DeleteMapping("/{checkResultIds}")
    @Operation(summary = "检查结果删除", description = "检查结果删除")
    public AjaxResult remove(@Parameter(description ="结果Id",required=true) @PathVariable Long[] checkResultIds)
    {
        return toAjax(ajCheckResultService.deleteCheckResultByIds(checkResultIds));
    }

    /**
     *
     * @param adjustCheckResult
     * @return
     */
    @PostMapping("adjustSubmit")
    @Operation(summary = "结果提交", description = "结果提交")
    public AjaxResult adjustSubmit(@RequestBody AdjustCheckResult adjustCheckResult){
        return ajCheckResultService.adjustSubmit(adjustCheckResult);
    }

    /**
     * 批量回调
     * @param patchCallback
     * @return
     */
    @PostMapping("patchCallback")
    @Operation(summary = "批量回调", description = "批量回调")
    public AjaxResult patchCallback(@RequestBody PatchCallback patchCallback){
        return ajCheckResultService.patchCallback(patchCallback);
    }

}


